home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_10_08
/
qcdemod.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-13
|
9KB
|
363 lines
///////////////////////////////////////////////////////
// QCDEMOD.CPP: Quadcode demo program for DOS
// Written by:
// Kenneth Van Camp
// RR #1 Box 1255
// East Stroudsburg, PA 18301
// (717)223-8620
//
// Functions -
// main main pgm entry point
// init_graphics initialize graphics
// Cursor::Cursor default constructor
// Cursor::Move move cursor
// RegionDisplay::Display display region
// RegionDisplay::Interact user interaction
// dos_yieldfunc yield function for build
//
///////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <graphics.h>
#include <conio.h>
#include <iostream.h>
#include "qc.h"
void init_graphics (void);
int dos_yieldfunc (int pct_complete);
const char CR = '\015', // carriage return code
ESC = '\033'; // escape code
int xres, // horiz screen resolution
yres, // vert screen resolution
shrink = TRUE, // shrink all qc's for plotting?
qccolor = 1, // color to paint quadcodes
xsize, // size of a single-division qc
ysize,
xoffs; // offset to center picture on scrn
// class RegionDisplay: A Region class with graphical
// display and interaction capabilities.
class RegionDisplay: public Region
{
public:
RegionDisplay // constructor from outline
(PointListHeader &vertex_list):
Region (vertex_list) { } // calls base constr.
void Display (void); // display on graphics screen
void Interact (void); // graphic interact function
}; // class RegionDisplay
// struct Cursor: Controls display of crosshair cursor.
struct Cursor
{
int xlen,
ylen,
xpos,
ypos;
Cursor (void);
void Move (int xdist, int ydist);
};
///////////////////////////////////////////////////////
// main: Main program entry point
int main (int argc, char **argv)
{
if (argc != 1)
{
if (argc != 2 || strcmp (argv[1], "-n") != 0)
{
cerr << "usage: QCdemo [-n]\n";
cerr << " where -n specifies no shrinkage\n";
return 1;
}
shrink = FALSE;
}
const int npts = 37;
const int ndiv = 128;
const int reduce = 1;
Point plist[npts] =
{
{ 5, 68}, { 28, 68}, { 32, 88}, { 33, 94},
{ 31,110}, { 30,113}, { 35,124}, { 51,125},
{ 63,127}, { 63,119}, { 67,116}, { 59,109},
{ 63,119}, { 63,127}, { 74,126}, { 80,125},
{ 88,112}, { 99,101}, {107, 98}, {113, 96},
{124, 98}, {122, 94}, {123, 91}, {121, 85},
{118, 78}, {108, 73}, { 96, 64}, { 85, 58},
{ 81, 50}, { 82, 46}, { 90, 38}, { 83, 25},
{ 72, 21}, { 58, 8}, { 55, 8}, { 54, 40},
{ 5, 40},
};
PointListHeader phdr =
{
npts, ndiv, plist
};
// Reduce to proper size
phdr.ndiv /= reduce;
int i;
for (i = 0; i < npts; i++)
{
phdr.pointptr[i].i /= reduce;
phdr.pointptr[i].j /= reduce;
}
// Set the yield function so user can interrupt.
SetRegionYieldFunc (dos_yieldfunc);
time_t tstart;
time (&tstart);
cout << "Building quadcode region (press Escape to Abort)\n";
// Build the region from a perimeter list
RegionDisplay reg (phdr);
time_t tend;
time (&tend);
if (reg.NumQC() == 0)
{
cout << "\nREGION BUILD ABORTED!\n";
return 0;
}
init_graphics();
// Display the region, then allow user interaction.
reg.Display();
reg.Interact();
restorecrtmode();
cout << "There are " << reg.NumQC() <<
" quadcodes in the region.\n";
cout << "Region was built in " <<
(long)difftime (tend, tstart) << " secs.\n";
return 0;
} // main
///////////////////////////////////////////////////////
// init_graphics: Initialize graphics under TC++.
void init_graphics (void)
{
// Initialize graphics
int driver = DETECT,
mode,
errc;
initgraph (&driver, &mode, getenv ("BGIDIR"));
if ((errc = graphresult()) != grOk)
{
cerr << "Graph Error: " << grapherrormsg (errc);
exit (1);
}
xres = getmaxx () + 1;
yres = getmaxy () + 1;
int maxcol = getmaxcolor ();
if (maxcol >= WHITE)
qccolor = WHITE;
else if (maxcol >= GREEN)
qccolor = GREEN;
} // init_graphics
///////////////////////////////////////////////////////
// Cursor::Cursor: Default constructor
Cursor::Cursor (void)
{
xpos = xres / 2;
ypos = yres / 2;
xlen = xres / 75;
ylen = yres / 50;
setwritemode (XOR_PUT);
setcolor (qccolor);
line (xpos - xlen, ypos, xpos + xlen, ypos);
line (xpos, ypos - ylen, xpos, ypos + ylen);
} // Cursor::Cursor
///////////////////////////////////////////////////////
// Cursor::Move: Move the cursor a specified distance.
void Cursor::Move (int xdist, int ydist)
// xdist is the dist to move right (left if negative)
// ydist is the dist to move down (up if negative)
{
// Erase the old cursor
setwritemode (XOR_PUT);
line (xpos - xlen, ypos, xpos + xlen, ypos);
line (xpos, ypos - ylen, xpos, ypos + ylen);
// Update in new position
xpos += xdist;
ypos += ydist;
xpos = max (0, xpos);
xpos = min (xres - 1, xpos);
ypos = max (0, ypos);
ypos = min (yres - 1, ypos);
line (xpos - xlen, ypos, xpos + xlen, ypos);
line (xpos, ypos - ylen, xpos, ypos + ylen);
} // Cursor::Move
///////////////////////////////////////////////////////
// RegionDisplay::Display: Display region graphically.
void RegionDisplay::Display (void)
// ndiv is the # of divisions to use on the screen
{
setcolor (qccolor);
setfillstyle (SOLID_FILL, qccolor);
// Find usable display area:
int ux = (float)xres / 1.5;
// Calculate size of a single-division quadcode:
xsize = ux / ndiv;
ysize = yres / ndiv;
xoffs = (xres - ux) * 0.5;
QCNode *qcn;
for (qcn = first_qcnode; qcn; qcn = qcn->next)
{
COORD i, j;
int nq;
qcn->ToIJ (i, j, nq);
COORD nqc_div = 1L << nq;
float qcfact = ndiv / nqc_div;
int xlen = xsize * qcfact;
int ylen = ysize * qcfact;
int x = xoffs + j * xsize * qcfact;
int y = i * ysize * qcfact;
if (shrink)
{
x++;
y++;
xlen -= 2;
ylen -= 2;
}
bar (x, y, x + xlen, y + ylen);
} // for qcn
} // RegionDisplay::Display
///////////////////////////////////////////////////////
// RegionDisplay::Interact: User interact with region.
void RegionDisplay::Interact (void)
{
Cursor csr;
setcolor (qccolor);
setfillstyle (SOLID_FILL, qccolor);
int nquits = MaxQuits();
int xbox = xres / 75;
int ybox = yres / 50;
int hispeed = yres / 50;
int speed = hispeed;
while(1)
{
// Update status box
int i = csr.ypos / ysize;
int j = (csr.xpos - xoffs) / xsize;
// Only check if within region limits
if (i >= 0 && i < ndiv && j >= 0 && j < ndiv)
{
QuadCode qc (i, j, nquits);
setwritemode (COPY_PUT);
if (InRegion (qc))
{
// In region - draw solid status box
bar (0, 0, xbox, ybox);
}
else
{
// Out of region - draw empty status box
setfillstyle (EMPTY_FILL, qccolor);
bar (0, 0, xbox, ybox);
setfillstyle (SOLID_FILL, qccolor);
rectangle (0, 0, xbox, ybox);
}
}
else
{
// Outside region limits - draw empty status box
setfillstyle (EMPTY_FILL, qccolor);
bar (0, 0, xbox, ybox);
setfillstyle (SOLID_FILL, qccolor);
rectangle (0, 0, xbox, ybox);
}
// Get last key in kybd buffer (no type-ahead)
int ch;
do
{
ch = getch();
if (ch == 0)
// Extended key codes (arrow keys)
ch = getch();
} while (kbhit());
switch (ch)
{
case 's': // toggle speed
case 'S':
if (speed == hispeed)
speed = 1;
else
speed = hispeed;